home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CUJ9104.ARJ / 9N04010A < prev    next >
Text File  |  1991-03-21  |  3KB  |  129 lines

  1. /* setlocale function */
  2. #include <ctype.h>
  3. #include <locale.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7.  
  8. #if _NCAT != 6
  9. #error wrong number of categories
  10. #endif
  11.         /* static data */
  12. static char *defname = NULL;<%-2>/* name of "" locale */
  13. "static int namalloc = 0;    /* _Locale._Name allocated */
  14. static const char * const nmcats[_NCAT] = {
  15.     NULL, "collate:", "ctype:", "monetary:",
  16.     "numeric:", "time:"};
  17. static struct lconv *pcats[_NCAT] = {NULL};
  18.  
  19.  
  20. /* set new locale */
  21. #undef setlocale
  22. char *setlocale(int cat, const char *lname)
  23.     {
  24.     if (cat < 0 || _NCAT <= cat)
  25.         return (NULL);    /* bad category */
  26.     if (lname == NULL)
  27.         return ((char *)_Locale._Name);
  28.     if (lname[0] == '\0')
  29.         {    /* find name of default locale */
  30.         char *s1, *s2;
  31.  
  32.  
  33.         if (defname)
  34.             lname = defname;
  35.         else if ((s1 = getenv("LOCALE")) != NULL
  36.             && (s2 = malloc(strlen(s1) + 1)) != NULL)
  37.             lname = defname = strcpy(s2, s1);
  38.         else
  39.             lname = "C";
  40.         }
  41.     if (_Clocale._Ctype == NULL)
  42.         {    /* flesh out "C" locale */
  43.         size_t i;
  44.  
  45.  
  46.         for (i = 0; i < _NCAT; ++i)
  47.             pcats[i] = &_Clocale;
  48.         _Clocale._Ctype = _Ctype;
  49.         _Clocale._Tolower = _Tolower;
  50.         _Clocale._Toupper = _Toupper;
  51.         }
  52.      {    /* set categories */
  53.     struct lconv *p;
  54.     int changed = 0;
  55.  
  56.  
  57.     if (cat != LC_ALL)
  58.         {    /* set a single category */
  59.         if ((p = _Getloc(nmcats[cat], lname)) == NULL)
  60.             return (NULL);
  61.         if (p != pcats[cat])
  62.             pcats[cat] = _Setloc(cat, p), changed = 1;
  63.         }
  64.     else
  65.         {    /* set all categories */
  66.         size_t i;
  67.  
  68.  
  69.         for (i = 0; ++i < _NCAT; )
  70.             {    /* set a category */
  71.             <%-2>if ((p = _Getloc(nmcats[i], lname)) == NULL)
  72. "                {    /* revert all on any failure */
  73.                 setlocale(LC_ALL, _Locale._Name);
  74.                 return (NULL);
  75.                 }
  76.             if (p != pcats[i])
  77.                 pcats[i] = _Setloc(i, p), changed = 1;
  78.             }
  79.         if ((p = _Getloc("", lname)) != NULL)
  80.             <%-3>pcats[0] = p; /* set only if LC_ALL
  81.                                     component */
  82. "        }
  83.     if (changed)
  84.         {    /* rebuild _Locale._Name */
  85.         char *s;
  86.         size_t i, n;
  87.         size_t len = strlen(pcats[0]->_Name);
  88.     
  89.         for (i = 0, n = 0; ++i < _NCAT; )
  90.             if (pcats[i] != pcats[0])
  91.                 {    /* count a changed subcategory */
  92.                 len += strlen(nmcats[i])
  93.                     + strlen(pcats[i]->_Name) + 1;
  94.                 ++n;
  95.                 }
  96.         if (n == 1)
  97.             {    /* uniform locale */
  98.             if (namalloc)
  99.                 free((void *)_Locale._Name);
  100.             _Locale._Name = pcats[1]->_Name;
  101.             namalloc = 0;
  102.             }
  103.         else if ((s = malloc(len + 1)) == NULL)
  104.             {    /* may be rash to try to roll back */
  105.             setlocale(LC_ALL, _Locale._Name);
  106.             return (NULL);
  107.             }
  108.         else
  109.             {    /* build complex name */
  110.             if (namalloc)
  111.                 free((void *)_Locale._Name);
  112.             _Locale._Name = s;
  113.             namalloc = 1;
  114.             s += strlen(strcpy(s, pcats[0]->_Name));
  115.             for (i = 0; ++i < _NCAT; )
  116.  
  117.                 if (pcats[i] != pcats[0])
  118.                     {    /* add a component */
  119.                     *s = ';';
  120.                     s += strlen(strcpy(s, nmcats[i]));
  121.                     <%-4>s += strlen(strcpy(s, pcats[i]->_Name));"
  122.                     }
  123.             }
  124.         }
  125.      }
  126.     return ((char *)_Locale._Name);
  127.     }
  128.  
  129.